﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using MacomberMapSystem.Common.Serialization;
using MacomberMapSystem.Common.CIM;
using MacomberMapSystem.Common.Database;
using MacomberMapSystem.Common.Internals;
using System.Data.OleDb;

namespace MacomberMapSystem.Common.Integration.Blackstart
{
    /// <summary>
    /// This class holds information on a blackstart element
    /// </summary>
    public class MM_Blackstart_Corridor_Element: MM_Serializable
    {
        #region Enumerations
        /// <summary>The collection of possible element activities</summary>
        public enum enumElementActivity
        {
            /// <summary>Energize a unit</summary>
            EnergizeUnit,
            /// <summary>Close a breaker</summary>
            Close_Breaker,
            /// <summary>Energize a line</summary>
            EnergizeLine,
            /// <summary>Reach a synchronization point</summary>
            ReachSynchPoint,
            /// <summary>Close a switch</summary>
            Close_Switch
        }
        #endregion

        #region Variable declarations
        /// <summary>The element associated with the action</summary>
        public CIM_Element AssociatedElement=null;

        /// <summary>The substation in which the action is to take place</summary>
        public CIM_Element Substation;

        /// <summary>The action to be carried out</summary>
        public enumElementActivity Action;

        /// <summary>The XML configuration for our element</summary>
        public XmlElement xConfig;

        /// <summary>The line number from the source spreadsheet</summary>
        public int LineNumber;

        /// <summary>The text from the source spreadsheet</summary>
        public string Text;
        #endregion

          #region Initialization
        /// <summary>
        /// Initialize a new blackstart corridor element
        /// </summary>
        /// <param name="xElem"></param>
        /// <param name="Model"></param>
        public MM_Blackstart_Corridor_Element(XmlElement xElem, MM_Database_Model Model)
            : base(xElem, Model)
        {
            this.xConfig = xElem;
            if (Model != null)
                AssignModel(Model);            
        }


        /// <summary>
        /// Initialize a new corridor element from 
        /// </summary>
        /// <param name="dRd"></param>
        public MM_Blackstart_Corridor_Element(OleDbDataReader dRd):base(null,null)
        {

        }

        /// <summary>
        /// Assign model information to our element
        /// </summary>
        /// <param name="Model"></param>
        public void AssignModel(MM_Database_Model Model)
        {
            Model.Substations.TryGetValue(xConfig.Attributes["Substation"].Value, out Substation);
            if (xConfig.HasAttribute("rdfID"))
                AssociatedElement = Model.FromRdfID(xConfig.Attributes["rdfID"].Value);
            else if (xConfig.Name == "Unit")
                AssociatedElement = Model.FromSubstationAndElementName(xConfig.Attributes["Substation"].Value, xConfig.Attributes["Name"].Value.Replace("#", ""), "cim:SynchronousMachine");
            else if (xConfig.Name == "Breaker")
                AssociatedElement = Model.FromSubstationAndElementName(xConfig.Attributes["Substation"].Value, xConfig.Attributes["Name"].Value.Replace("#", ""), "cim:Breaker");
            else if (xConfig.Name == "Line")
                Model.Lines.TryGetValue(MM_Type_Converter.TitleCase(xConfig.Attributes["Name"].Value.Replace("#", "")), out AssociatedElement);

            //Check for units ending in the target number
            if (xConfig.Name == "Unit" && AssociatedElement == null && Model.Substations.ContainsKey(xConfig.Attributes["Substation"].Value))
                foreach (CIM_Element Elem2 in Model.Substations[xConfig.Attributes["Substation"].Value].Elements)
                    if (Elem2.TypeName == "cim:SynchronousMachine" && Elem2.Name.EndsWith(xConfig.Attributes["Name"].Value.Replace("#", "")))
                        AssociatedElement = Elem2;
            if (AssociatedElement != null)
                AssignComponents(Action, Substation, AssociatedElement);
        }


        /// <summary>
        /// Initialize a new blackstart corridor element
        /// </summary>
        /// <param name="Action"></param>
        /// <param name="Substation"></param>
        /// <param name="AssociatedElement"></param>
        /// <param name="SiblingElement"></param>
        /// <param name="InsertBefore"></param>
        /// <param name="TargetElement"></param>        
        public MM_Blackstart_Corridor_Element(enumElementActivity Action, CIM_Element Substation, CIM_Element AssociatedElement, XmlElement TargetElement, XmlElement SiblingElement, bool InsertBefore): base(null, null)
        {
            //First, create our Xml element
            xConfig = TargetElement.OwnerDocument.CreateElement(AssociatedElement.ElemType);
            AssignComponents(Action, Substation, AssociatedElement);
            if (SiblingElement == null)
                TargetElement.AppendChild(xConfig);
            else if (InsertBefore)
                TargetElement.InsertBefore(xConfig, SiblingElement);
            else
                TargetElement.InsertAfter(xConfig, SiblingElement);
        }

        /// <summary>
        /// Assign components and update our XML.
        /// </summary>
        /// <param name="Action"></param>
        /// <param name="Substation"></param>
        /// <param name="AssociatedElement"></param>
        
        public void AssignComponents(enumElementActivity Action, CIM_Element Substation, CIM_Element AssociatedElement)
        {
            this.Action = Action;
            this.Substation = Substation;
            this.AssociatedElement = AssociatedElement;
            xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("Action")).Value = Action.ToString();
            if (Substation != null)
            {
                xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("Substation")).Value = Substation.Name;
                xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("SubRdfID")).Value = Substation.rdfID.ToString();
            }
            xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("rdfID")).Value = AssociatedElement.rdfID.ToString();
            xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("TEID")).Value = AssociatedElement.TEID.ToString();
            if (AssociatedElement.ElemType == "Line")
                xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("Name")).Value = AssociatedElement.LineName;
            else
                xConfig.Attributes.Append(xConfig.OwnerDocument.CreateAttribute("Name")).Value = AssociatedElement.Name;
        }
        #endregion

        /// <summary>
        /// Report the name of our string 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Action.ToString() + " " + Substation.Name + " " + AssociatedElement.ToString();
        }
    }
}
